package org.kl.bf.service.basic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.kl.bf.entity.basic.Function;
import org.kl.bf.entity.basic.Menu;
import org.kl.bf.entity.basic.Role;
import org.kl.bf.entity.basic.User;
import org.kl.bf.entity.easyui.EasyuiGrid;
import org.kl.bf.entity.easyui.EasyuiTreeNode;
import org.kl.bf.entity.easyui.EasyuiUtils;
import org.kl.bf.repository.basic.MenuDao;
import org.kl.bf.repository.basic.UserDao;
import org.kl.bf.utils.CRUDUtils;
import org.kl.bf.utils.KLDynamicSpecifications;
import org.kl.bf.utils.KLSearchFilter;
import org.kl.bf.web.base.BasicController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springside.modules.utils.Collections3;

/**
 * @Author hqm
 * @CreateTime 2014-3-13 下午9:11:30
 */
// Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional
public class MenuService {

	private MenuDao menuDao;
	@Autowired
	private UserDao userDao;
	private int i = 0;

	@Autowired
	private FunctionService functionService;

	public Menu getMenu(String guid) {
		return menuDao.findOne(guid);
	}

	public void saveMenu(Menu entity) {
		menuDao.save(entity);
	}

	public void deleteMenu(String guid) {
		menuDao.delete(guid);
	}

	/**
	 * 删除多条记录
	 * 
	 * @param ids
	 */
	public String multiDelete(String ids) {
		String[] idArray = StringUtils.split(ids, ",");
		for (String id : idArray) {
			if (StringUtils.isNotBlank(id)) {
				List<Menu> menus = menuDao.findByMenuParentIdOrderByDisplayOrderAsc(id);
				if (menus != null) {
					for (int j = 0; j < menus.size(); j++) {
						multiDelete(menus.get(j).getId());

					}
				}
				List<Function> functions = functionService.getFunctionByMenuId(id);
				String fids = "";
				if (functions != null) {
					for (int k = 0; k < functions.size(); k++) {
						fids += (functions.get(k).getId() + ",");
					}
					System.out.println("测试：" + fids);
					String ss = functionService.multiDelete(fids);
					System.out.println(ss);
				}

				Menu menu = menuDao.find(Menu.class, id);
				if (menu != null) {
					menuDao.delete(id);
					i++;
				}

			}
		}
		return "删除" + i + "条记录";

	}

	public List<Menu> getAllMenu() {
		return (List<Menu>) menuDao.findAll();
	}

	public Menu findByMenuUrl(String menuUrl) {
		List<Menu> menuList = menuDao.findByMenuUrl(menuUrl);
		if (Collections3.isNotEmpty(menuList)) {
			return menuList.get(0);
		}
		return null;
	}

	/**
	 * 生成treeGrid
	 * 
	 * @return
	 */
	public EasyuiGrid treeGrid(boolean withFunctions) {
		List<Menu> result = menuDao.findAll(new Sort(Direction.ASC, "displayOrder"));
		if (withFunctions) {
			for (Menu menu : result) {
				menu.setFunctionForJson(menu.getFunctions());
			}
		}
		EasyuiGrid grid = new EasyuiGrid();
		grid.setRows(result);
		grid.setTotal(result == null ? 0 : result.size());
		return grid;
	}

	public Page<Menu> getMenu(Map<String, Object> searchParams, int pageNumber, int pageSize, String sortType) {
		PageRequest pageRequest = CRUDUtils.buildPageRequest(pageNumber, pageSize, sortType, "desc");
		Specification<Menu> spec = buildSpecification(searchParams);
		return menuDao.findAll(spec, pageRequest);
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<Menu> buildSpecification(Map<String, Object> searchParams) {
		Map<String, KLSearchFilter> filters = KLSearchFilter.parse(searchParams);
		Specification<Menu> spec = KLDynamicSpecifications.byKLSearchFilter(filters.values(), Menu.class);
		return spec;
	}

	@Autowired
	public void setMenuDao(MenuDao menuDao) {
		this.menuDao = menuDao;
	}

	/**
	 * 根据rootId生成树形菜单（平滑数据）
	 * 
	 * @param id
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<EasyuiTreeNode> tree(String rootId) {
		List<Menu> menus;
		if (StringUtils.isEmpty(rootId)) {
			menus = menuDao.findAll();
		} else {
			menus = menuDao.findByRootIdOrderByDisplayOrderAsc(rootId);
			Menu menuRoot = menuDao.findOne(rootId);
			menus.add(menuRoot);
		}
		List<EasyuiTreeNode> easyuiTree = new ArrayList<EasyuiTreeNode>();
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String contextPath = request.getContextPath();
		for (Menu menu : menus) {
			easyuiTree.add(EasyuiUtils.buildMenuTree(menu, contextPath));
		}
		return easyuiTree;
	}

	/**
	 * 获取根节点菜单
	 * 
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Menu> root() {
		List<Menu> result = menuDao.findByRootIdOrderByDisplayOrderAsc("-1");
		return result;
	}

	/**
	 * 查询所有的菜单，只查三层，即菜单定义时只设定三层
	 * 
	 * @return
	 */
	public List<Menu> getThreeLayerTreeMenu() {
		List<Menu> rootMenus = new ArrayList<Menu>();
		if (BasicController.isSysManager()) {
			List<Menu> Menus = menuDao.findByMenuParentIdIsNullOrderByDisplayOrderAsc();
			for (Menu rootMenu : Menus) {
				rootMenu.setLayer(1);
				List<Menu> secondMenus = menuDao.findByMenuParentIdOrderByDisplayOrderAsc(rootMenu.getId());
				rootMenu.setChildMenuList(secondMenus);
				for (Menu secordMenu : secondMenus) {
					secordMenu.setLayer(2);
					secordMenu.setParentMenuName(rootMenu.getMenuName());
					List<Menu> thridMenus = menuDao.findByMenuParentIdOrderByDisplayOrderAsc(secordMenu.getId());
					for (Menu thridMenu : thridMenus) {
						thridMenu.setLayer(3);
						thridMenu.setParentMenuName(secordMenu.getMenuName());
					}
					secordMenu.setChildMenuList(thridMenus);
				}
			}
			rootMenus = Menus;
		} else {
			User user = userDao.findOne(BasicController.getCurrentUserId());
			Set<Role> roleSet = user.getRoleSet();
			for (Role role : roleSet) {
				Set<Menu> roleMenusSet = role.getRoleMenus();
				for (Menu menu : roleMenusSet) {
					if (StringUtils.isEmpty(menu.getMenuParentId())) {
						if (!rootMenus.contains(menu)) {
							rootMenus.add(menu);
						}
					}
				}
			}
			for (Menu rootMenu : rootMenus) {
				rootMenu.setLayer(1);
				List<Menu> secondMenus = new ArrayList<Menu>();
				for (Role role : roleSet) {
					Set<Menu> roleMenusSet = role.getRoleMenus();
					for (Menu menu : roleMenusSet) {
						if (StringUtils.isNotEmpty(menu.getMenuParentId())) {
							if (menu.getMenuParentId().equals(rootMenu.getId())) {
								if (!secondMenus.contains(menu)) {
									secondMenus.add(menu);
								}
							}
						}
					}
				}
				Collections.sort(secondMenus, new Comparator<Menu>() {
					public int compare(Menu arg0, Menu arg1) {
						if (arg0.getDisplayOrder() != null && arg1.getDisplayOrder() != null) {
							return arg0.getDisplayOrder().compareTo(arg1.getDisplayOrder());
						} else {
							return 0;
						}

					}
				});
				rootMenu.setChildMenuList(secondMenus);
				for (Menu secordMenu : secondMenus) {
					secordMenu.setLayer(2);
					secordMenu.setParentMenuName(rootMenu.getMenuName());
					List<Menu> thridMenus = new ArrayList<Menu>();
					for (Role role : roleSet) {
						Set<Menu> roleMenusSet = role.getRoleMenus();
						for (Menu menu : roleMenusSet) {
							if (StringUtils.isNotEmpty(menu.getMenuParentId())) {
								if (menu.getMenuParentId().equals(secordMenu.getId())) {
									if (!thridMenus.contains(menu)) {
										thridMenus.add(menu);
									}
								}
							}
						}
					}
					Collections.sort(thridMenus, new Comparator<Menu>() {
						public int compare(Menu arg0, Menu arg1) {
							if (arg0.getDisplayOrder() != null && arg1.getDisplayOrder() != null) {
								return arg0.getDisplayOrder().compareTo(arg1.getDisplayOrder());
							} else {
								return 0;
							}

						}
					});
					for (Menu thridMenu : thridMenus) {
						thridMenu.setLayer(3);
						thridMenu.setParentMenuName(secordMenu.getMenuName());
					}
					secordMenu.setChildMenuList(thridMenus);
				}
			}
			Collections.sort(rootMenus, new Comparator<Menu>() {
				public int compare(Menu arg0, Menu arg1) {
					if (arg0.getDisplayOrder() != null && arg1.getDisplayOrder() != null) {
						return arg0.getDisplayOrder().compareTo(arg1.getDisplayOrder());
					} else {
						return 0;
					}

				}
			});
		}
		return rootMenus;
	}

	/**
	 * 查询所有的菜单【平铺到一层】，只查三层，即菜单定义时只设定三层
	 * 
	 * @return
	 */
	public List<Menu> getAllMenu(List<Menu> rootMenus) {
		List<Menu> menuList = new ArrayList<Menu>();
		for (Menu rootMenu : rootMenus) {
			menuList.add(rootMenu);
			for (Menu secordMenu : rootMenu.getChildMenuList()) {
				menuList.add(secordMenu);
				for (Menu thridMenu : secordMenu.getChildMenuList()) {
					menuList.add(thridMenu);
				}
			}
		}
		return menuList;
	}
}
